import uuid
from django.http import JsonResponse
from django import forms
from datetime import datetime

from BloodSpiderModel.DjangoResponseTool.response_dict import response_dict, get_first_error, get_page
from BloodSpiderAPI import models
from BloodSpiderAPI.apis.order import utils as order_utils
from django.db.models import Q


# 订单表单验证
class OrderForm(forms.ModelForm):
    class Meta:
        model = models.Order
        fields = ['user', 'product', 'points', 'status']
    
    # 自定义验证方法
    def clean_points(self):
        points = self.cleaned_data.get('points')
        if points < 0:  # 确保积分非负
            raise forms.ValidationError("积分不能为负数")
        return points
        
    def clean_status(self):
        status = self.cleaned_data.get('status')
        # 确保状态值在有效范围内
        valid_status = [1, 2, 3, 4, 5]
        if status not in valid_status:
            raise forms.ValidationError("订单状态值无效")
        return status


# 创建订单
def create_order(request):
    """
    创建新订单API
    支持POST请求
    参数: uid(用户ID), product_id(商品ID)
    返回: 创建成功的订单信息或错误信息
    """
    if request.method != 'POST':
        return response_dict(message="请使用POST请求", code=1)
    
    product_id = request.POST.get('product_id')
  
    if not product_id:
        return response_dict(message="商品ID不能为空", code=1)
    
    try:
        # 检查用户是否存在
        user = models.User.objects.get(uid=request.user.uid)
        # 检查商品是否存在
        product = models.Product.objects.get(pid=product_id)
        
        # 检查库存是否足够
        if product.stock <= 0:
            return response_dict(message="商品库存不足", code=1)
        
        # 检查用户积分是否足够
        if user.points < product.points:
            return response_dict(message="用户积分不足", code=1)
        
        # 创建订单
        order = models.Order()
        order.oid = str(uuid.uuid4())
        order.user = user
        order.product = product
        order.points = product.points
        order.status = 2  # 已支付状态
        order.save()
        
        # 更新商品库存和已售数量
        product.stock -= 1
        product.sold += 1
        product.save()
        
        # 扣除用户积分
        user.points -= product.points
        user.save()
        
        response = order_utils.utils_model_to_dict(order)
        return response_dict(message="订单创建成功", code=0, data=response)
    except models.User.DoesNotExist:
        return response_dict(message="用户不存在", code=1)
    except models.Product.DoesNotExist:
        return response_dict(message="商品不存在", code=1)
    except Exception as e:
        return response_dict(message=f"创建失败: {str(e)}", code=1)


# 获取单个订单
def get_order(request):
    """
    获取单个订单API
    支持POST请求
    参数: oid(订单ID)
    返回: 订单信息或错误信息
    """
    if request.method != 'POST':
        return response_dict(message="请使用POST请求", code=1)
    
    oid = request.POST.get('oid')
    if not oid:
        return response_dict(message="订单ID不能为空", code=1)
    
    try:
        order = models.Order.objects.get(oid=oid, user=request.user)
        response = order_utils.utils_model_to_dict(order)
        return response_dict(message="订单信息获取成功", code=0, data=response)
    except models.Order.DoesNotExist:
        return response_dict(message="订单不存在", code=1)
    except Exception as e:
        return response_dict(message=f"获取失败: {str(e)}", code=1)


# 更新订单
def update_order(request):
    """
    更新订单API
    支持POST请求
    参数: oid(订单ID), 其他可选字段(status)
    返回: 更新后的订单信息或错误信息
    
    特殊规则:
    1. 订单状态为"已完成"(4)或"已取消"(5)的记录不允许再次更新
    2. 当订单状态更新为"已取消"(5)时，需执行以下操作：
       - 向对应用户返还积分
       - 将相关商品库存加1
       - 商品已售数量减1
    """
    if request.method != 'POST':
        return response_dict(message="请使用POST请求", code=1)
    
    oid = request.POST.get('oid')
    if not oid:
        return response_dict(message="订单ID不能为空", code=1)
    
    try:
        order = models.Order.objects.get(oid=oid)
        
        # 检查订单状态是否为已完成或已取消
        if order.status == 4 or order.status == 5:
            return response_dict(message="已完成或已取消的订单不允许再次更新", code=1)
        
        # 仅更新传入的字段
        data = request.POST.dict()
        # 移除oid，避免更新主键
        data.pop('oid', None)
        
        # 保存原始状态用于判断
        original_status = order.status
        
        # 验证更新的字段
        for key, value in data.items():
            if hasattr(order, key):
                if key == 'status':
                    try:
                        value = int(value)
                        valid_status = [1, 2, 3, 4, 5]
                        if value not in valid_status:
                            return response_dict(message="订单状态值无效", code=1)
                        order.status = value
                    except ValueError:
                        return response_dict(message="状态必须是整数", code=1)
                elif key == 'points':
                    # 积分不允许手动更新
                    return response_dict(message="积分不允许手动更新", code=1)
                else:
                    setattr(order, key, value)
        
        # 处理状态变更为已取消的逻辑
        if 'status' in data and int(data['status']) == 5:
            # 向用户返还积分
            user = order.user
            user.points += order.points
            user.save()
            
            # 更新商品库存和已售数量
            product = order.product
            product.stock += 1
            product.sold -= 1
            product.save()
        
        order.save()
        response = order_utils.utils_model_to_dict(order)
        return response_dict(message="订单更新成功", code=0, data=response)
    except models.Order.DoesNotExist:
        return response_dict(message="订单不存在", code=1)
    except Exception as e:
        return response_dict(message=f"更新失败: {str(e)}", code=1)


# 删除订单
def delete_order(request):
    """
    删除订单API
    支持POST请求
    参数: oid(订单ID)
    返回: 删除结果信息
    """
    if request.method != 'POST':
        return response_dict(message="请使用POST请求", code=1)
    
    oid = request.POST.get('oid')
    if not oid:
        return response_dict(message="订单ID不能为空", code=1)
    
    try:
        order = models.Order.objects.get(oid=oid)
        order.delete()
        return response_dict(message="订单删除成功", code=0)
    except models.Order.DoesNotExist:
        return response_dict(message="订单不存在", code=1)
    except Exception as e:
        return response_dict(message=f"删除失败: {str(e)}", code=1)


# 获取全部订单列表
def get_order_list(request):
    """
    获取全部订单列表API
    支持POST请求
    参数: keyword(名称模糊查询), page(页码), page_size(每页数量)
    返回: 订单列表或错误信息
    """
    if request.method != 'POST':
        return response_dict(message="请使用POST请求", code=1)
    
    keyword = request.POST.get('keyword', '')
    page = request.POST.get('page', 1)
    page_size = request.POST.get('page_size', 10)
    
    # 构建查询条件
    query = Q()
    if keyword:
        # 模糊查询商品名称
        query &= Q(product__name__icontains=keyword, user=request.user)
    
    orders = models.Order.objects.filter(query).order_by('-create_time')
    
    # 分页处理
    page_data = get_page(orders, page_size, page)
    
    # 转换数据格式
    order_list = []
    for order in page_data['page']['object_list']:
        order_list.append(order_utils.utils_model_to_dict(order))
    
    page_data['page']['object_list'] = order_list
    
    return response_dict(message="订单列表获取成功", code=0, data=page_data)